﻿using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using orm.efcore.api.Entities;

namespace orm.efcore.api.Controllers
{
    /// <summary>
    /// 进阶操作
    /// </summary>
    public class AdvanceController(CoreDbContext dbContext) : EfCoreBaseController(dbContext)
    {
        /// <summary>
        /// 事务
        /// </summary>
        [HttpPost]
        public async Task<IActionResult> Transaction()
        {
            await using var tran = await DbContext.Database.BeginTransactionAsync();

            try
            {
                DbContext.Order.Add(new()
                {
                    Number = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    TotalPrice = 1,
                    CreateTime = DateTime.Now
                });
                await DbContext.SaveChangesAsync();

                DbContext.Order.Add(new()
                {
                    Number = DateTime.Now.ToString("yyyyMMddHHmmss"),
                    TotalPrice = 2,
                    CreateTime = DateTime.Now
                });
                await DbContext.SaveChangesAsync();

                await tran.CommitAsync();
            }
            catch (Exception) 
            {
                await tran.RollbackAsync();
                throw;
            }

            return Ok("Success");
        }

        /// <summary>
        /// 自动比较更改然后修改
        /// </summary>
        [HttpPatch]
        public async Task<IActionResult> Update(Order order)
        { 
            var existingOrder = await DbContext.Order.FindAsync(order.Id);
            if (existingOrder != null)
            {
                DbContext.Attach(existingOrder); // 因为配置了查询默认不跟踪实体，先附加一下
                DbContext.Entry(existingOrder).CurrentValues.SetValues(order);
                return Ok(await DbContext.SaveChangesAsync() > 0);
            }

            return Ok("Null");
        }

        /// <summary>
        /// 关联查询最新明细
        /// </summary>
        [HttpGet]
        public async Task<IActionResult> LatestDetail()
        {
            // 方法一：使用 Include
            //return Ok(await DbContext.Order
            //    .Include(o => o.OrderDetails
            //        .OrderByDescending(od => od.Id)
            //        .Take(1))
            //    .ToListAsync());

            // 方法二：使用 Select（会加载明细数据是因为这样写会生成对应的 SQL）
            return Ok(await DbContext.Order
                .Select(o => new
                {
                    Order = o,
                    LatestDetail = o.OrderDetails.FirstOrDefault
                        (od => od.Id == o.OrderDetails.Max(od => od.Id))
                })
                .ToListAsync());
        }
    }
}
